package com.agv.core.dao.dataExtractor;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;

public class LigasResultSetExtractor implements ResultSetExtractor{
	
	private List<String> listaPKs = new ArrayList<String>();
	private Map<String,String> nombTablanombPK = new HashMap<String, String>();
	private Map<String,String> nombreCampoNombreTabla = new HashMap<String, String>();

	@Override
	public Map<String,Map<String,Object>> extractData(ResultSet rs) throws SQLException,
			DataAccessException {
		
		ResultSetMetaData rsmd = rs.getMetaData();
		int numCols = rsmd.getColumnCount();
		
		Map<String,Object> objProperties = new HashMap<String,Object>();
		Map<String,Map<String,Object>> nombCampoAndProperties = new LinkedHashMap<String, Map<String,Object>>();
		
		List<String> nombresCampos = new ArrayList<String>();
		Map<String,String> nombrePKValorPK = new HashMap<String, String>();
		
		
		for (int i = 1; i <= numCols; i++) {
			
			//llenamos el objeto de propiedades de cada campo q no es un pk
			if( !listaPKs.contains( rsmd.getColumnName(i) ) ){//si el campo no es un PK

				objProperties = new HashMap<String,Object>();
				objProperties.put( "nombreTabla", nombreCampoNombreTabla.get(rsmd.getColumnName(i)) );
				objProperties.put( "tipoCampo", rsmd.getColumnClassName(i) );
				//objProperties.put( "nombreCampo", rsmd.getColumnName(i) );
				objProperties.put( "longCampo", rsmd.getColumnDisplaySize(i) );	
			
				nombCampoAndProperties.put( rsmd.getColumnName(i), objProperties );
				nombresCampos.add(rsmd.getColumnName(i));
			}
		}
		
		
		
		
		
//		valor     ,   8 -- esto sale del resultSet normal --ok
//		editable  ,   false --esto se lo agregamos en el dao
//		type,         string --ok
//		longitud  ,   longitud del campo --ok
//		nombreTabla,  nombre_tabla --ok
//		nombreCampo,  nombre_campo --ok
//		nombrePK,     nombrePK -- se lo agregamos en el dao
//		valorPK,      valorPK -- esto sale del resultSet normal
		
		while( rs.next() ){
			
			//agregamos los valores de cada uno de los campos
			for (int i = 1; i <= numCols; i++) {
				
				//si el nombre del campo es una pk
				if( listaPKs.contains( rsmd.getColumnName(i) ) ){
					nombrePKValorPK.put(rsmd.getColumnName(i), rs.getString(i));//guardamos el nombre de la pk y su valor
						
				}else{//si es un campo normal
					
					//agregamos su valor a su objeto de propiedades 
					Map<String,Object> objProp = nombCampoAndProperties.get( rsmd.getColumnName(i) );
					objProp.put( "valor", rs.getObject(i) );
					nombCampoAndProperties.put( rsmd.getColumnName(i), objProp );	
						
				}
			}
			
		}

		
		//agregamos los nombres y valores de las PKS a los objetos de propiedades
		for (int i = 0; i < nombresCampos.size(); i++) {

			//obtenemos el objeto de propiedades de cada campo
			Map<String,Object> objProp = nombCampoAndProperties.get( nombresCampos.get(i) );
	
			//obtenemos el nombre de la tabla del campo
			String nombreTablaCampo = (String)objProp.get("nombreTabla");
			
			//con el nombre de la tabla obtenemos el PK de la tabla
			String nombrePK = nombTablanombPK.get(nombreTablaCampo);
			
			//con el nombre del PK obtenemos el valor del PK
			String valorPK = nombrePKValorPK.get(nombrePK);
			
			//agregamos el nombre del PK y su valor a cada uno de los objetos de propiedades de cada campo
			objProp.put("nombrePK", nombrePK );
			objProp.put("valorPK", valorPK);
			
			//actualizando el objeto de propiedades del campo
			nombCampoAndProperties.put(nombresCampos.get(i), objProp);

		}
		
		
		return nombCampoAndProperties;
	}



	public List<String> getListaPKs() {
		return listaPKs;
	}



	public void setListaPKs(List<String> listaPKs) {
		this.listaPKs = listaPKs;
	}



	public Map<String, String> getNombTablanombPK() {
		return nombTablanombPK;
	}



	public void setNombTablanombPK(Map<String, String> nombTablanombPK) {
		this.nombTablanombPK = nombTablanombPK;
	}
	
	
	
	public Map<String, String> getNombreCampoNombreTabla() {
		return nombreCampoNombreTabla;
	}



	public void setNombreCampoNombreTabla(Map<String, String> nombreCampoNombreTabla) {
		this.nombreCampoNombreTabla = nombreCampoNombreTabla;
	}

	
	
	
}
